#include "stl-test.h"
#include <map>
#include <vector>
#include <iterator>
#include <string>
#include <list>
#include <iostream>
#include <algorithm>
#include "string-util.h"
using namespace std;

STLTest* STLTest::runTest()
{
	Teams teams;
	
	string teamName="team";
	string memberName="member1";
	vector<string> members;
	members.reserve(NumberOfMembersPerTeam);
	psln(members.capacity());

	for(int i=0; i<NumberOfTeam; ++i) {
		teamName.append("1");

		memberName = "member";
		members.clear();
		for (int j=0; j<NumberOfMembersPerTeam; ++j) {
			memberName.append("1");
			members.push_back(memberName);
		}

		teams[teamName] = members;
	}

	Teams::iterator it = teams.begin();
	while (it != teams.end()) {
		p(it->first);
		pln(" { ");
		for (size_t j=0; j<it->second.size(); ++j) {
			pln(it->second[j]);
		}
		pln("}");
		++it;
	}
	return this;
}

STLTest::STLTest()
{
	pln("STLTest()");
}

STLTest::~STLTest()
{
	pln("~STLTest()");
}

STLTest* STLTest::testMap()
{
    MapTest mt;
    //mt.canReturnedIteratorChangeItsMap();
    mt.testInsert();
	return this;
}

int dealWithInt( int i1 ) 
{
	return i1 + 1 - 1 + 1;
}

bool sortInt(int i1, int i2) {
	int newI1 = dealWithInt(i1);
	int newI2 = dealWithInt(i2);
	return newI1 < newI2;	
}

class GIntSorter {
	bool operator () (int i1, int i2) {
		return i1 > i2;
	}
};

STLTest* STLTest::testSorter() {
	list<int> testList;
	int a[] = {12, 23, 9, 2, 1};
	testList.assign(a, a+5);
	//copy(a, a+5, testList.begin()); // error!
	copy(testList.begin(), testList.end(), ostream_iterator<int>(cout, ","));
	cr;
	//std::sort(testList.begin(), testList.end(), GIntSorter());
	//testList.sort(sortInt);		// ok
	//testList.sort(IntSorter());	// ok
	//testList.sort();				// ok
	testList.sort(&memSorter);
	// testList.sort(GIntSorter()); // error !!
	pc("after sort");
	copy(testList.begin(), testList.end(), ostream_iterator<int>(cout, ","));
	cr;
	return this;
}

bool STLTest::memSorter( int param1, int param2 ) {
	return param2 < param1;
}

STLTest* STLTest::testTransform()
{
	ItemContaniner ic;
	ic.reserve(10);
	for (size_t i=0; i<10; ++i) {
		ic.push_back(Item(rand()));
	}
	Item transformItemFunc(Item );
	ItemContaniner icResult;
	icResult.resize(ic.size());
	transform(ic.begin(), ic.end(), icResult.begin(), transformItemFunc);
	copy(icResult.begin(), icResult.end(), ostream_iterator<Item>(cout, ","));

	return this;
}

STLTest::Item transformItemFunc(STLTest::Item item) {
	return STLTest::Item(item.data() * item.data());
}

STLTest::Item STLTest::transformItem( STLTest::Item item )
{
	return STLTest::Item(item.data() * item.data());
}

std::ostream& operator << (std::ostream& os, const STLTest::Item & item) {
	os << item.mData;
	return os;
}
